#include "user_cfg.h"
#include "nrf_process.h"
#include "gzll.h"
#include "gui_guider.h"
#include "delay.h"


#define USART_SET           USART2
USART_TypeDef* USART_TEST = USART_SET;

void RCC_ClkConfiguration(void)
{
	RCC_DeInit();

	RCC_HSICmd(ENABLE);
	while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);         //等待HSI准备好

	RCC_PLLCmd(DISABLE);

	FLASH_SetLatency(FLASH_Latency_2);

	RCC_PLLConfig(RCC_PLLSource_HSI_Div1,RCC_PLLMul_32);     // 8 * 32 = 256MHZ

	RCC_PLLCmd(ENABLE);
	while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);

	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

	RCC_HCLKConfig(RCC_SYSCLK_Div1);
	RCC_PCLK1Config(RCC_HCLK_Div1);
	RCC_PCLK2Config(RCC_HCLK_Div1);

	RCC_LSICmd(ENABLE);
	while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
}


void TIM2_DeInit(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    // 禁用TIM2中断
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
    NVIC_Init(&NVIC_InitStructure);

    // 禁用TIM2时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE);

    // 复位TIM2寄存器到默认状态
    TIM_DeInit(TIM2);
}

void TIM2_Configuration(uint16_t u16Data)
{
	RCC_ClocksTypeDef clocks;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能

	//定时器TIM2初始化
	TIM_TimeBaseStructure.TIM_Period = u16Data - 1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler = 256 - 1; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE ); //使能指定的TIM2中断,允许更新中断

	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

	TIM_Cmd(TIM2, ENABLE);  //使能TIMx
}


void TIM3_DeInit(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
    // 禁用TIM3时钟，关闭定时器时钟源
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, DISABLE);

    // 禁用TIM3中断

    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
    NVIC_Init(&NVIC_InitStructure);

    // 复位TIM3寄存器到默认状态
    TIM_DeInit(TIM3);
}

void TIM3_Configuration(void)
{
	RCC_ClocksTypeDef clocks;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

	//定时器TIM3初始化
	TIM_TimeBaseStructure.TIM_Period = 1000 - 1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler = 256 - 1; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

	//中断优先级NVIC设置
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
	NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器

	TIM_Cmd(TIM3, ENABLE);  //使能TIMx
}

void Test_Gpio_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA, ENABLE );

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
    GPIO_ResetBits(GPIOC, GPIO_Pin_13);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA, GPIO_Pin_1);
}

void Charge_Deteciton(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOB,ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

}

#if 1
void Lcd_Backlight_Pwm(unsigned int data)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);	//使能定时器4时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟


   //设置该引脚为复用输出功能,输出TIM4 CH3的PWM脉冲波形
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //TIM_CH4
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO

	//定时器TIM4初始化
	TIM_TimeBaseStructure.TIM_Period = 999; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler = 256 - 1; //设置用来作为TIMx时钟频率除数的预分频值
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

	//初始化TIM4 Channel3 PWM模式
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
    if (data < 5) {
        data = 5;
    }
	TIM_OCInitStructure.TIM_Pulse = data*10 - 1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
	TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
	TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
	TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
	TIM_OC4Init(TIM4, &TIM_OCInitStructure);

	TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
	TIM_ARRPreloadConfig(TIM4, ENABLE); //使能TIMx在ARR上的预装载寄存器

	TIM_Cmd(TIM4, ENABLE);  //使能TIMx
	TIM_CtrlPWMOutputs(TIM4, ENABLE);    //高级定时器主意打开
}
#endif

void UART_Configuration(uint32_t bound)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
    if (USART_SET == USART2) {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        USART_InitStructure.USART_BaudRate = bound;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

        USART_Init(USART_TEST, &USART_InitStructure);
        USART_Cmd(USART_TEST, ENABLE);
    } else if (USART_SET == USART1) {
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);

        USART_InitStructure.USART_BaudRate = bound;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

        USART_Init(USART_TEST, &USART_InitStructure);
        USART_Cmd(USART_TEST, ENABLE);
    }
}


void Spi2_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );
    GPIO_InitStructure.GPIO_Pin = 0;
    GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_13;             // SPI2_CLK
    GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_14;             // SPI2_MISO
    GPIO_InitStructure.GPIO_Pin |= GPIO_Pin_15;             // SPI2_MOSI
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;         // 推挽复用功能模式
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    SPI_InitTypeDef  SPI_InitStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE );
	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;      // 双线双向全双工
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		                    // 主机模式
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		                // 8位帧结构
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;		                        // 时钟极性为低
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	                        // 第一边沿采样
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		                        // CS片选软件控制
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;		// 256 / 32 = 8M SPI
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	                    // 数据高位先发
	SPI_InitStructure.SPI_CRCPolynomial = 7;	                            // CRC值计算的多项式
	SPI_Init(SPI2, &SPI_InitStructure);

    // SPI_CalculateCRC(SPI2, DISABLE);

    // SPI_NSSInternalSoftwareConfig(SPI2, SET);

	SPI_Cmd(SPI2, ENABLE);
}


#if 1

#define CONV_CHANNEL_NUM  		1
#define VREF              		(5000)
#define ADC_TEST_CHANNEL_PIN	(GPIO_Pin_0)
uint8_t ADC_CovChannel[1] = {ADC_Channel_0};
uint8_t ADC_SampleTIME[1] = {ADC_SampleTime_239Cycles5};
uint32_t DAM_ADC_Value[1];

void ADC_Configuration(void)
{
	// 定义变量和结构体
	uint32_t i;
	ADC_InitTypeDef ADC_InitStructure;  // ADC初始化结构体
	GPIO_InitTypeDef GPIO_InitStructure;  // GPIO初始化结构体
	NVIC_InitTypeDef NVIC_InitStructure;
	// 使能GPIOA和ADC1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);

	// 配置PA0为模拟输入模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  // 选择PA0引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  // 引脚速度50MHz
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;  // 模拟输入模式
	GPIO_Init(GPIOA, &GPIO_InitStructure);  // 应用配置到GPIOA

	// 配置ADC时钟 (PCLK2分频16)
	RCC_ADCCLKConfig(RCC_PCLK2_Div32);
	// 重置ADC1配置
	ADC_DeInit(ADC1);

	// 配置ADC工作模式
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  // 独立模式
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;  // 扫描模式使能
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;  // 禁止连续转换
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  // 无外部触发
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  // 数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;  // 转换通道数量:1
	ADC_Init(ADC1, &ADC_InitStructure);  // 应用ADC配置

	// 使能ADC1
	ADC_Cmd(ADC1, ENABLE);


	NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	ADC_RegularChannelConfig(ADC1 , ADC_Channel_0 , 1 , ADC_SampleTime_239Cycles5);
	ADC_AnalogWatchdogSingleChannelConfig(ADC1,ADC_Channel_0);
	ADC_AnalogWatchdogThresholdsConfig(ADC1,4095,2206);//只限制低压3.6V
    // ADC_AnalogWatchdogThresholdsConfig(ADC1,2048,1024);//1.65V---0.825V
	ADC_AnalogWatchdogCmd(ADC1,ADC_AnalogWatchdog_SingleRegEnable);

	ADC_ITConfig(ADC1,ADC_IT_AWD,ENABLE);

	// ADC校准
	ADC_ResetCalibration(ADC1);  // 重置校准寄存器
	while(ADC_GetResetCalibrationStatus(ADC1));  // 等待校准重置完成
	ADC_StartCalibration(ADC1);  // 开始校准
	while(ADC_GetCalibrationStatus(ADC1));  // 等待校准完成

}

void ADC1_2_IRQHandler(void)
{
    static uint8_t cnt;
	ADC_ITConfig(ADC1,ADC_IT_AWD,DISABLE);
	if(SET == ADC_GetFlagStatus(ADC1,ADC_FLAG_AWD))
	{
		ADC_ClearFlag(ADC1,ADC_FLAG_AWD);
		ADC_ClearITPendingBit(ADC1,ADC_IT_AWD);
        if (++cnt >= 5 && !app_para.charge_flag) {
            cnt = 0;
            ui_load_scr_animation(&guider_ui, &guider_ui.low_bat, guider_ui.low_bat_del, NULL, setup_scr_low_bat, LV_SCR_LOAD_ANIM_NONE, 0, 0, false, true);
            TimeOut_Record(&app_para.tout.power_low_ui_back_tout, 3000);
            app_para.power_low_flag = true;
        }
		printf("ADC Awd is Happened. Code Value = %d \r\n",ADC1->DR);
	}
	ADC_ITConfig(ADC1,ADC_IT_AWD,ENABLE);
}
#endif

/**
 * @brief 失能ADC及相关中断
 * @note 停止转换、禁用中断并关闭ADC外设
 */
void ADC_Disable(void)
{
    // 停止ADC软件转换
    ADC_SoftwareStartConvCmd(ADC1, DISABLE);

    // 禁用ADC转换完成中断
    ADC_ITConfig(ADC1, ADC_IT_EOC, DISABLE);

    // 清除ADC中断标志
    ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);

    // 禁用ADC外设
    ADC_Cmd(ADC1, DISABLE);

    // 禁用DMA通道（如果使用DMA）
    DMA_Cmd(DMA1_Channel1, DISABLE);
}



void GPIO_Configuration(void)
{
	uint8_t i;

	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|\
							RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOG,ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

	for(i = 0; i < (GPIOG_BASE-GPIOA_BASE)/0x400; i++)
	{
		GPIO_Init((GPIO_TypeDef *)((APB2PERIPH_BASE + (i+3)*0x0400)), &GPIO_InitStructure);

	}

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void WAKEUP_Configuration(void)
{
	EXTI_InitTypeDef EXTI_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD|\
							RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOF|RCC_APB2Periph_GPIOG,ENABLE);

	EXTI_ClearITPendingBit(EXTI_Line7 | EXTI_Line6 | EXTI_Line8 | EXTI_Line9 | EXTI_Line10 | EXTI_Line11 | EXTI_Line12 | EXTI_Line1);
	EXTI_InitStructure.EXTI_Line = EXTI_Line7 | EXTI_Line6 | EXTI_Line8 | EXTI_Line9 | EXTI_Line10 | EXTI_Line11 | EXTI_Line12 | EXTI_Line1;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);



	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOF, &GPIO_InitStructure);
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOF, GPIO_PinSource6);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOF, GPIO_PinSource7);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource9);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource8);



    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource10);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource11);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource12);

    if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1)) {
        EXTI_InitStructure.EXTI_Line = EXTI_Line1;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);
    } else {
        EXTI_ClearITPendingBit(EXTI_Line1);
        EXTI_InitStructure.EXTI_Line = EXTI_Line1;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);
    }
	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource1);

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
}

lv_ui cur_ui;
extern unsigned int counter;
void Enter_LowPowerMode(void)
{
    //nrf24低功耗配置
    static uint16_t sta_buf[1] = {0};
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
    Nrf24L01_EXTI_Line2_Disable();
    ADC_Disable();

    GPIO_Configuration();
    TIM2_DeInit();
    TIM3_DeInit();

    WAKEUP_Configuration();
    app_para.work_sta = false;
	PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);
    sta_buf[0] = 0XFFFF;
    MHFLASH_Write(MH_FLASH_POWER, sta_buf, 1);
    NVIC_SystemReset();
}

// extern lv_ui guider_ui;
void Exit_LowPowerMode(void)
{
    // if (app_para.work_sta)
    //     return ;
    // app_para.cur_mode = RUNNING_MODE;
    #if 0

    #endif
}

void Enter_LowPower_Handle(void)
{
    static uint16_t sta_buf[1] = {0};
    sta_buf[0] = 1;
    MHFLASH_Write(MH_FLASH_POWER, sta_buf, 1);
    NVIC_SystemReset();
}

int SER_PutChar (int ch)
{
	while(!USART_GetFlagStatus(USART_TEST,USART_FLAG_TC));
	USART_SendData(USART_TEST, (uint8_t) ch);

	return ch;
}

 int fputc(int c, FILE *f)
 {
 	/* Place your implementation of fputc here */
 	/* e.g. write a character to the USART */
 	if (c == '\n')
 	{
 		SER_PutChar('\r');
 	}
 	return (SER_PutChar(c));
 }




void Wwdg_Init(void)
{
	NVIC_InitTypeDef NVIC_InitStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG, ENABLE);
    WWDG_SetPrescaler(WWDG_Prescaler_1); // 使用芯片支持的最高分频值(8)
	WWDG_SetWindowValue(0x70); // 设置最小窗口值以最大化喂狗时间窗口
	WWDG_Enable(0x7F);
    // 添加喂狗提示注释
    // 需在主循环或定时器中断中定期调用 WWDG_SetCounter(0x70); 喂狗
    // 喂狗必须在计数器降至0x70~0x40之间进行
}

void Wdt_Init(void)
{
	IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
	IWDG_SetPrescaler(IWDG_Prescaler_64);
	IWDG_SetReload(0x7FF);
	IWDG_ReloadCounter();
	IWDG_Enable();
}




//读取指定地址的半字(16位数据)
//faddr:读地址(此地址必须为2的倍数!!)
//返回值:对应数据.
u16 MHFLASH_ReadHalfWord(u32 faddr)
{
	return *(vu16*)faddr;
}

//不检查的写入
//WriteAddr:起始地址
//pBuffer:数据指针
//NumToWrite:半字(16位)数
void MHFLASH_Write_NoCheck(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
{
	u16 i;
	for(i=0;i<NumToWrite;i++)
	{
		FLASH_ProgramHalfWord(WriteAddr,pBuffer[i]);
	    WriteAddr+=2;//地址增加2.
	}
}
//从指定地址开始写入指定长度的数据
//WriteAddr:起始地址(此地址必须为2的倍数!!)
//pBuffer:数据指针
//NumToWrite:半字(16位)数(就是要写入的16位数据的个数.)

#define MH_SECTOR_SIZE	1024

u16 MHFLASH_BUF[MH_SECTOR_SIZE/2];//最多是2K字节
void MHFLASH_Write(u32 WriteAddr,u16 *pBuffer,u16 NumToWrite)
{
	u32 secpos;	   //扇区地址
	u16 secoff;	   //扇区内偏移地址(16位字计算)
	u16 secremain; //扇区内剩余地址(16位字计算)
 	u16 i;
	u32 offaddr;   //去掉0X08000000后的地址
	if(WriteAddr<MH_FLASH_BASE||(WriteAddr>=(MH_FLASH_BASE+1024*MH_FLASH_SIZE)))return;//非法地址
	FLASH_Unlock();						//解锁
	offaddr=WriteAddr-MH_FLASH_BASE;		//实际偏移地址.
	secpos=offaddr/MH_SECTOR_SIZE;			//扇区地址
	secoff=(offaddr%MH_SECTOR_SIZE)/2;		//在扇区内的偏移(2个字节为基本单位.)
	secremain=MH_SECTOR_SIZE/2-secoff;		//扇区剩余空间大小
	if(NumToWrite<=secremain)secremain=NumToWrite;//不大于该扇区范围
	while(1)
	{
		MHFLASH_Read(secpos*MH_SECTOR_SIZE+MH_FLASH_BASE,MHFLASH_BUF,MH_SECTOR_SIZE/2);//读出整个扇区的内容
		for(i=0;i<secremain;i++)//校验数据
		{
			if(MHFLASH_BUF[secoff+i]!=0XFFFF)break;//需要擦除
		}
		if(i<secremain)//需要擦除
		{
			FLASH_ErasePage(secpos*MH_SECTOR_SIZE+MH_FLASH_BASE);//擦除这个扇区
			for(i=0;i<secremain;i++)//复制
			{
				MHFLASH_BUF[i+secoff]=pBuffer[i];
			}
			MHFLASH_Write_NoCheck(secpos*MH_SECTOR_SIZE+MH_FLASH_BASE,MHFLASH_BUF,MH_SECTOR_SIZE/2);//写入整个扇区
		}else MHFLASH_Write_NoCheck(WriteAddr,pBuffer,secremain);//写已经擦除了的,直接写入扇区剩余区间.
		if(NumToWrite==secremain)break;//写入结束了
		else//写入未结束
		{
			secpos++;				//扇区地址增1
			secoff=0;				//偏移位置为0
		   	pBuffer+=secremain;  	//指针偏移
			WriteAddr+=secremain*2;	//写地址偏移
		   	NumToWrite-=secremain*2;	//字节(16位)数递减
			if(NumToWrite>(MH_SECTOR_SIZE/2))secremain=MH_SECTOR_SIZE/2;//下一个扇区还是写不完
			else secremain=NumToWrite;//下一个扇区可以写完了
		}
	};
	FLASH_Lock();//上锁
}


//从指定地址开始读出指定长度的数据
//ReadAddr:起始地址
//pBuffer:数据指针
//NumToWrite:半字(16位)数
void MHFLASH_Read(u32 ReadAddr,u16 *pBuffer,u16 NumToRead)
{
	u16 i;
	for(i=0;i<NumToRead;i++)
	{
		pBuffer[i]=MHFLASH_ReadHalfWord(ReadAddr);//读取2个字节.
		ReadAddr+=2;//偏移2个字节.
	}
}

//WriteAddr:起始地址
//WriteData:要写入的数据
void Test_Write(u32 WriteAddr,u16 WriteData)
{
	MHFLASH_Write(WriteAddr,&WriteData,1);//写入一个字
}


